package com.jie.other.compose.study04

import android.view.accessibility.CaptioningManager.CaptionStyle
import androidx.annotation.DrawableRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.listSaver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import com.jie.other.R
import kotlinx.coroutines.flow.filter

@Composable
fun ToDestinationUserInput(
    onToDestinationChange : (String) -> Unit = {}
) {
    val state = rememberEditUserInputState(hint = "Please Input")
    CraneEditUserInput(
        state = state,
        caption = "To",
        vectorImageId = R.drawable.profile_picture
    )
    val curToDestinationChange by rememberUpdatedState(onToDestinationChange)
    LaunchedEffect(state) {
        snapshotFlow { state.text }
            .filter { !state.isHint }
            .collect {
                curToDestinationChange(state.text)
            }
    }
}

@Composable
fun rememberEditUserInputState(hint: String): EditUserInputState =
    rememberSaveable(hint, saver = EditUserInputState.Saver) {
        EditUserInputState(hint, hint)
    }

class EditUserInputState(private val hint: String, initText: String) {

    var text by mutableStateOf(initText)
        private set

    fun updateText(newText : String) {
        text = newText
    }

    val isHint: Boolean
        get() = hint == text

    companion object {
        val Saver: Saver<EditUserInputState, *> = listSaver(
            save = { listOf(it.hint, it.text) },
            restore = {
                EditUserInputState(
                    hint = it[0],
                    initText = it[1]
                )
            }
        )
    }
}

@Composable
fun CraneEditUserInput(
    state: EditUserInputState = rememberEditUserInputState(hint = ""),
    caption : String? = null,
    @DrawableRes vectorImageId : Int? = null,
) {
    CraneBaseUserInput(
        caption = caption,
        showCaption = {!state.isHint},
        tintIcon = {!state.isHint},
        vectorImageId = vectorImageId
    ) {
        BasicTextField(
            value = state.text,
            onValueChange = { state.updateText(it)},
            textStyle = if (state.isHint) {
                TextStyle(color = LocalContentColor.current)
            } else {
                MaterialTheme.typography.body1.copy(color = LocalContentColor.current)
            },
            cursorBrush = SolidColor(LocalContentColor.current),
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight()
                .background(Color.Red)
                .padding(vertical = 8.dp),
        )
    }
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun CraneBaseUserInput(
    modifier: Modifier = Modifier,
    onClick : () -> Unit = {},
    caption : String? = null,
    @DrawableRes vectorImageId : Int? = null,
    showCaption: () -> Boolean = {true},
    tintIcon : () -> Boolean,
    tint : Color = LocalContentColor.current,
    content: @Composable () -> Unit
) {
    Surface(
        modifier = modifier,
        onClick = onClick,
        color = MaterialTheme.colors.primaryVariant,
    ) {
        Row(Modifier.padding(all = 12.dp)) {
            if (vectorImageId !=  null) {
                Icon(
                    modifier = Modifier.size(24.dp, 24.dp),
                    painter = painterResource(id = vectorImageId),
                    tint = if (tintIcon()) tint else Color(0x80FFFFFF),
                    contentDescription = null
                )
                Spacer(modifier = Modifier.width(8.dp))
            }
            if (caption != null && showCaption()) {
                Text(
                    text = caption,
                    modifier = Modifier.align(Alignment.CenterVertically),
                    style = TextStyle(color = tint)
                )
                Spacer(modifier = Modifier.width(8.dp))
            }
            Row(
                modifier = Modifier
                    .weight(1f)
                    .align(Alignment.CenterVertically),
            ) {
                content()
            }
        }
    }
}

